package cn.xo68.boot.auth.core.web;

import cn.xo68.core.util.StringTools;
import org.apache.oltu.oauth2.common.error.OAuthError;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.ParameterStyle;
import org.apache.oltu.oauth2.rs.request.OAuthAccessResourceRequest;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.LinkedList;
import java.util.List;

/**
 *  oauth2 令牌 识别
 * @author wucie
 * @date 2018-8-8
 */
public class Oauth2TokenDiscern {

    private static final Logger logger=LoggerFactory.getLogger(Oauth2TokenDiscern.class);

    private OAuthAccessResourceRequest oAuthAccessResourceRequest;

    private HttpServletRequest request;
    private final boolean supportHeader;
    private final boolean supportQuery;
    private final boolean supportCookie;

    private final SimpleCookie simpleCookie;

    private String accessToken;

    public String getAccessToken() {
        return accessToken;
    }

    public Oauth2TokenDiscern(HttpServletRequest request, boolean supportHeader, boolean supportQuery, boolean supportCookie, SimpleCookie simpleCookie) throws OAuthSystemException, OAuthProblemException{
        this.request=request;
        this.supportHeader = supportHeader;
        this.supportQuery = supportQuery;
        this.supportCookie = supportCookie;
        this.simpleCookie = simpleCookie;

        this.validate();


    }

    private void  validate() throws OAuthSystemException, OAuthProblemException{
        List<ParameterStyle> parameterStyles=new LinkedList<>();
        if(supportHeader){
            parameterStyles.add(ParameterStyle.HEADER);
        }
        if(supportQuery){
            parameterStyles.add(ParameterStyle.QUERY);
        }
        ParameterStyle[] styles=new ParameterStyle[parameterStyles.size()];
        try {
            oAuthAccessResourceRequest=new OAuthAccessResourceRequest(request,parameterStyles.toArray(styles));
            this.accessToken=oAuthAccessResourceRequest.getAccessToken();
        } catch (OAuthSystemException e) {
            throw e;
        } catch (OAuthProblemException e) {
            logger.debug("从头、参数中识别令牌异常", e);
        }

        if(StringTools.isEmpty(this.accessToken) && supportCookie){
            //令牌
            String cookieToken =simpleCookie.readValue(this.request, null);

            if(StringTools.isEmpty(this.accessToken) && StringTools.isNotEmpty(cookieToken)){
                this.accessToken=cookieToken;
            }else if (StringTools.isNotEmpty(this.accessToken) && StringTools.isNotEmpty(cookieToken)){
                throw OAuthProblemException.error(OAuthError.TokenResponse.INVALID_REQUEST,
                        "Found more than one mechanism for authenticating client");
            }else if(StringTools.isEmpty(this.accessToken) && StringTools.isEmpty(cookieToken)){
                throw OAuthProblemException.error(OAuthError.TokenResponse.INVALID_REQUEST,
                        "OAuth parameters were not found");
            }
        }


    }
}
